<template>
  <div id="app-container" style="text-align: center;">
    <ButtonGroup>
      <Tooltip content="下载BPMN流程图" placement="top">
        <Button class="bnt" @click="handleDownloadXml()">
          <Icon custom="iconfont icon-xml3"/>
        </Button>
      </Tooltip>
      <Tooltip content="下载SVG图片" placement="top">
        <Button class="bnt" @click="handleDownloadSvg()">
          <Icon type="md-image"/>
        </Button>
      </Tooltip>
      <Tooltip content="导入" placement="top">
        <Button class="bnt" @click="handleOpen()">
          <input style="display: none" id="openFile" ref="openFile" type="file" @change="onOpenFile($event)"/>
          <Icon custom="iconfont icon-open"/>
        </Button>
      </Tooltip>
      <!--          <Tooltip content="保存到服务器" placement="top">-->
      <Tooltip content="保存" placement="top">
        <Button class="bnt" @click="handleSave()">
          <!--              <Icon custom="iconfont icon-save"/>-->
          <Icon type="md-cloud-upload"/>
        </Button>
      </Tooltip>
      <Tooltip content="撤销" placement="top">
        <Button class="bnt" @click="handleUndo()">
          <Icon custom="iconfont icon-undo"/>
        </Button>
      </Tooltip>
      <Tooltip content="重做" placement="top">
        <Button class="bnt" @click="handleRedo()">
          <Icon custom="iconfont icon-redo"/>
        </Button>
      </Tooltip>
      <Tooltip content="缩放到实际尺寸" placement="top">
        <Button class="bnt" @click="handleZoom()">
          <Icon custom="iconfont icon-shijichicun1"/>
        </Button>
      </Tooltip>
      <Tooltip content="放大" placement="top">
        <Button class="bnt" @click="handleZoom(0.1)">
          <Icon custom="iconfont icon-zoomOut"/>
        </Button>
      </Tooltip>
      <Tooltip content="缩小" placement="top">
        <Button class="bnt" @click="handleZoom(-0.1)">
          <Icon custom="iconfont icon-zoomIn"/>
        </Button>
      </Tooltip>
      <Tooltip content="全屏/退出" placement="top">
        <Button class="bnt" @click="handleFullScreen()">
          <Icon custom="iconfont icon-fullscreencopy"/>
        </Button>
      </Tooltip>
      <Tooltip content="快捷键" placement="top">
        <Button class="bnt" @click="showShortcutKeys()">
          <Icon custom="iconfont icon-keyboard"/>
        </Button>
      </Tooltip>
      <Tooltip content="自动排版" placement="top">
        <Button class="bnt">
          <Icon custom="iconfont icon-paiban"/>
        </Button>
      </Tooltip>
      <!--          <Tooltip content="左对齐" placement="top">
                  <Button class="bnt">\n</Button>
                </Tooltip>
                <Tooltip content="水平对齐" placement="top">
                  <Button class="bnt">\n</Button>
                </Tooltip>
                <Tooltip content="右对齐" placement="top">
                  <Button class="bnt">\n</Button>
                </Tooltip>
                <Tooltip content="顶部对齐" placement="top">
                  <Button class="bnt">\n</Button>
                </Tooltip>
                <Tooltip content="垂直对齐" placement="top">
                  <Button class="bnt">\n</Button>
                </Tooltip>
                <Tooltip content="底部对齐" placement="top">
                  <Button class="bnt">\n</Button>
                </Tooltip>-->
      <Tooltip content="验证" placement="top">
        <Button class="bnt" @click="validateDiagrame('bottom')">
          <Icon custom="iconfont icon-yanzheng1"/>
        </Button>
      </Tooltip>
    </ButtonGroup>
  </div>
</template>
<script>
import { xmlStr2 } from '../xmlStr2'

export default {
  name: 'DesignHeader',
  components: {},
  props: {
    bpmnModeler: {
      type: Object,
      required: true
    },
    modelInfo: {
      type: Object,
      require: true,
      default: null
    }
  },
  data () {
    return {
      state: {
        scale: 1 // 流程图比例
      },
      modelDiagramXml: ''
    }
  },
  watch: {
    modelInfo: {
      handler (n, o) {
        if (n.key) {
          this.renderDiagram(n.modelXml, 'open')
        }
      }, deep: true
    }
  },
  computed: {},
  mounted () {
  },
  methods: {
    download (type, data, name) {
      let dataTrack = ''
      const a = document.createElement('a')
      switch (type) {
        case 'xml':
          dataTrack = 'bpmn'
          break
        case 'svg':
          dataTrack = 'svg'
          break
        default:
          break
      }
      var bpmnName = this.getProcess().name || this.getProcess().id
      var filename = bpmnName + '.' + dataTrack
      name = name || `${filename}`
      a.setAttribute('href', `data:application/bpmn20-xml;charset=UTF-8,${encodeURIComponent(data)}`)
      a.setAttribute('target', '_blank')
      a.setAttribute('dataTrack', `diagram:download-${dataTrack}`)
      a.setAttribute('download', name)
      document.body.appendChild(a)
      a.click()
      document.body.removeChild(a)
    },

    // 导入xml文件
    handleOpenFile (e) {
      const that = this
      const file = e.target.files[0]
      const reader = new FileReader()
      let data = ''
      reader.readAsText(file)
      reader.onload = function (event) {
        data = event.target.result
        // that.renderDiagram(data, 'open')
        that.updateModelInfo({
          key: that.bpmnModeler.get('canvas').getRootElement().id,
          modelXml: data,
          milliseconds: new Date().getMilliseconds()
        })
      }
    },
    // 更新modelInfo
    updateModelInfo (info) {
      const that = this
      let parent = that.$parent
      while (!parent.diagramManagerImportXml) {
        parent = parent['$parent']
      }
      parent.diagramManagerImportXml(Object.assign(info))
    },
    // 保存
    async handleSave () {
      const { xml } = await this.bpmnModeler.saveXML()
      const nodeIdList = []
      try {
        for (var index in this.bpmnModeler._definitions.$model.ids._seed.hats) {
          if (this.bpmnModeler._definitions.$model.ids._seed.hats[index].$type === 'bpmn:Process') continue
          nodeIdList.push(this.bpmnModeler._definitions.$model.ids._seed.hats[index].id)
        }
      } catch (e) {
        console.error(e)
      }
      try {
        var nodeList = []
        for (var index2 in this.bpmnModeler.get('elementRegistry').getAll()) {
          if (this.bpmnModeler.get('elementRegistry').getAll()[index2].type === 'label' ||
            this.bpmnModeler.get('elementRegistry').getAll()[index2].type === 'bpmn:Process') {
            continue
          }
          // nodeList.push(this.$refs.panel.elementToNodeInfo(this.bpmnModeler.get('elementRegistry').getAll()[index2]))
        }
        console.log('nodeList:' + JSON.stringify(nodeList))
      } catch (e) {
        console.error(e)
      }
      // 检验
      /*console.info(this.bpmnModeler.get('linting')._active)
      if (!this.bpmnModeler.get('linting')._active) {
        this.bpmnModeler.get('linting').toggle()
        this.$Message.warning('当前流程未校验，现自动开启校验，如果校验无误后，请再点击保存按钮！')
        return
      }
      console.log(this.bpmnModeler.get('linting'))
      console.log(this.bpmnModeler.get('linting')._button.innerText.split(' Errors')[0])
      const validateError = Number(this.bpmnModeler.get('linting')._button.innerText.split(' Errors')[0])
      if (validateError > 0) {
        this.$Message.error('当前流程未通过校验，请修改后再保存！')
        // 先放开
        return
      }
      console.log('validateError:' + validateError)*/
      this.saveXmlHeader(xml)
    },
    saveXmlHeader(xml){
      const postData = Object.assign(this.modelInfo, {
        modelXml: xml.replace(/ns0:/g, 'flowable:')
      })
      console.log(postData)
      this.$emit("saveXmlHeader",postData);
    },
    // 前进
    handleRedo () {
      this.bpmnModeler.get('commandStack').redo()
    },

    // 后退
    handleUndo () {
      this.bpmnModeler.get('commandStack').undo()
    },

    // 对齐
    align (type) {
      const selection = this.bpmnModeler.get('selection').get()
      if (selection === 'undefined' || selection === null || selection === '' || selection.length === 0) {
        this.$Message.error('选择排版节点为空，请选择需对齐具体节点！')
        return
      }
      this.bpmnModeler.get('alignElements').trigger(selection, type)
    },

    // 下载SVG格式
    async handleDownloadSvg () {
      const { svg } = await this.bpmnModeler.saveSVG()
      this.download('svg', svg)
      this.modelDiagramSvg = svg
    },

    // 下载XML格式
    async handleDownloadXml () {
      const { xml } = await this.bpmnModeler.saveXML()
      this.download('xml', xml.replace(/ns0:/g, 'flowable:'))
    },

    // 流程图放大缩小
    handleZoom (radio) {
      console.log('handleZoom () ')
      const newScale = !radio
        ? 1.0 // 不输入radio则还原
        : this.state.scale + radio <= 0.2 // 最小缩小倍数
          ? 0.2
          : this.state.scale + radio
      this.bpmnModeler.get('canvas').zoom(newScale)
      this.state.scale = newScale
    },

    handleOpen () {
      document.getElementById('openFile').click()
    },
    onOpenFile (files) {
      this.handleOpenFile(files)
      this.$refs.openFile.value = null
    },
    handleFullScreen () {
      const element = document.documentElement
      // 判断是否已经是全屏
      // 如果是全屏，退出
      if (this.fullscreen) {
        if (document.exitFullscreen) {
          document.exitFullscreen()
        } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen()
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen()
        }
      } else {
        // 否则，进入全屏
        if (element.requestFullscreen) {
          element.requestFullscreen()
        } else if (element.webkitRequestFullScreen) {
          element.webkitRequestFullScreen()
        } else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen()
        } else if (element.msRequestFullscreen) {
          // IE11
          element.msRequestFullscreen()
        }
      }
      // 改变当前全屏状态
      this.fullscreen = !this.fullscreen
    },
    showShortcutKeys () {
      const showcutKeysHtml =
        '	 <table>  ' +
        '        <tbody>  ' +
        '          <tr>  ' +
        '            <td>撤销</td>  ' +
        '            <td class="binding"><code>ctrl + Z</code></td>  ' +
        '          </tr>  ' +
        '          <tr>  ' +
        '            <td>重做</td>  ' +
        '            <td class="binding"><code>ctrl + ⇧ + Z</code></td>  ' +
        '          </tr>  ' +
        '          <tr>  ' +
        '            <td>全选</td>  ' +
        '            <td class="binding"><code>ctrl + A</code></td>  ' +
        '          </tr>  ' +
        '          <tr>  ' +
        '            <td>滚动（垂直）</td>  ' +
        '            <td class="binding"><code>ctrl + Scrolling</code></td>  ' +
        '          </tr>  ' +
        '          <tr>  ' +
        '            <td>滚动（水平）</td>  ' +
        '            <td class="binding"><code>ctrl + ⇧ + Scrolling</code></td>  ' +
        '          </tr>  ' +
        '          <tr>  ' +
        '            <td>直接编辑</td>  ' +
        '            <td class="binding"><code>E</code></td>  ' +
        '          </tr>  ' +
        '          <tr>  ' +
        '            <td>拖拽工具</td>  ' +
        '            <td class="binding"><code>H</code></td>  ' +
        '          </tr>  ' +
        '          <tr>  ' +
        '            <td>自由套索工具</td>  ' +
        '            <td class="binding"><code>L</code></td>  ' +
        '          </tr>  ' +
        '          <tr>  ' +
        '            <td>空间移动工具</td>  ' +
        '            <td class="binding"><code>S</code></td>  ' +
        '          </tr>  ' +
        '        </tbody>  ' +
        '      </table>  '

      this.$Modal.info({
        content: showcutKeysHtml
      })
    },
    // autuLayout() {
    //   this.getProcessDiagramXML()
    //   /*  const alignToOrigin = this.bpmnModeler.get('alignToOrigin')
    //   console.log('alignToOrigin:' + alignToOrigin)
    //   alignToOrigin.align() */
    //   var AutoLayout = require('bpmn-auto-layout')
    //
    //   const autoLayout = new AutoLayout()
    //
    //   this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
    //     if (err) {
    //       this.$Message.error(err)
    //     } else {
    //       (async() => {
    //         var layoutedDiagramXML = await autoLayout.layoutProcess(xml)
    //
    //         console.log('layoutedDiagramXML:' + layoutedDiagramXML)
    //       })()
    //       // vkbeautify.xml(xml.replace(/ns0:/g, 'flowable:'))
    //     }
    //   })
    // },
    getProcessDiagramXML () {
      if (this.bpmnModeler._customElements != null && this.bpmnModeler._customElements.length > 0) {
        // 将自定义的元素 加入到 _definitions
        this.bpmnModeler._definitions.rootElements[0].flowElements = this.bpmnModeler._definitions.rootElements[0].flowElements.concat(this.bpmnModeler._customElements[0])
      }
      this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
        if (err) {
          this.$Message.error(err)
        } else {
          this.modelDiagramXml = xml
          // vkbeautify.xml(xml.replace(/ns0:/g, 'flowable:'))
        }
      })
    },
    getProcessDiagramSvg () {
      this.bpmnModeler.saveSVG({ format: true }, (err, data) => {
        console.log('err：' + err)
        this.modelDiagramSvg = data
      })
    },
    validateDiagrame () {
      this.modelInfo.metaInfo = new Date().getSeconds()
      this.bpmnModeler.get('linting').toggle()
    },
    renderDiagram (xml) {
      if (xml === '') {
        xml = xmlStr2
        xml = xml.replace(/Process_1/g, this.modelInfo.key)
        xml = xml.replace(/Process_name_1/g, this.modelInfo.name)
        // xml = xml.replace(/UserTask_Id/g, new Ids([32, 36, 1]).nextPrefixed('UserTask_'))
        // xml = xml.replace(/SequenceFlow_Id/g, new Ids([32, 36, 1]).nextPrefixed('SequenceFlow_'))
      }
      this.bpmnModeler.importXML(xml, err => {
        if (err) {
          console.log('init diagram error' + err)
          window.alert(' 请选择正确的bpmn 或 XML 文件 ！' + err)
          return
        } else {
          console.log('init diagram success!')
          // 让图能自适应屏幕
          this.bpmnModeler.get('canvas').zoom('fit-viewport')
          // 设置 流程图预览速度
          /*this.bpmnModeler.get('animation').setAnimationSpeed(1.5)
          document.getElementsByClassName('toggle-mode')[0].innerHTML = '流程模拟 <span class="toggle"><i class="fa fa-toggle-off"></i></span>'*/
        }
      })
    },
    getProcessElement () {
      return this.bpmnModeler.getDefinitions().rootElements[0]
    },
    getProcess () {
      const element = this.getProcessElement()
      console.log(element)
      return {
        id: element.id,
        name: element.name,
        category: element.$parent.targetNamespace ?? ''
      }
    },
  }
}
</script>

<style>
.bnt {
  margin-left: 10px;
}

</style>

